import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ComponentPropsType } from "../../components/QusetionComponent";
import { getNextSelectId, insertNewComponent } from "./utils";
import { nanoid } from "@reduxjs/toolkit";
import { arrayMove } from "@dnd-kit/sortable";
import cloneDeep from "lodash.clonedeep";
export type ComponentInfoType = {
  fe_id: string;
  type: string;
  title: string;
  isHidden?: boolean;
  isLocked?: boolean;
  props: ComponentPropsType;
};

export type ComponentStateType = {
  selectId: string;
  componentList: Array<ComponentInfoType>;
  copiedComponent: ComponentInfoType | null;
};
const INIT_STATE: ComponentStateType = {
  selectId: "",
  componentList: [],
  copiedComponent: null,
};

export const componentsSlice = createSlice({
  name: "components",
  initialState: INIT_STATE,
  reducers: {
    //重置所有组件
    resetComponents: (
      state: ComponentStateType,
      action: PayloadAction<ComponentStateType>
    ) => {
      return action.payload;
    },
    //修改选中selectId
    changeSelectId: (
      state: ComponentStateType,
      action: PayloadAction<string>
    ) => {
      //不可变数据,只能返回新的数据,不可修改
      // state.selectId=action.payload
      return {
        ...state,
        selectId: action.payload,
      };
    },
    //添加新组件
    addComponent: (
      state: ComponentStateType,
      action: PayloadAction<ComponentInfoType>
    ) => {
      const newComponent = action.payload;
      return insertNewComponent(state, newComponent);
    },
    //修改组件属性
    updateComponentProps: (
      state: ComponentStateType,
      action: PayloadAction<{ fe_id: string; newProps: ComponentPropsType }>
    ) => {
      const { fe_id, newProps } = action.payload;
      const updatedComponents = state.componentList.map((component) =>
        component.fe_id === fe_id
          ? { ...component, props: newProps }
          : component
      );

      return {
        ...state,
        componentList: updatedComponents,
      };
    },
    //删除选中组件
    deleteComponent: (state: ComponentStateType) => {
      const { componentList, selectId } = state;
      const updateComponentList = componentList.filter(
        (c) => c.fe_id !== selectId
      );
      const newSelectId = getNextSelectId(selectId, componentList);
      return {
        ...state,
        componentList: updateComponentList,
        selectId: newSelectId,
      };
    },
    //显示/隐藏 组件
    hiddenComponent: (
      state: ComponentStateType,
      action: PayloadAction<{ fe_id: string; isHidden: boolean }>
    ) => {
      const { componentList = [] } = state;
      const { fe_id, isHidden } = action.payload;
      // const currenComponent = componentList.find((c) => c.fe_id === fe_id);
      // if (currenComponent) {
      //   currenComponent.isHidden = isHidden;
      // }
      // const updateComponentList = componentList.map((c) =>
      //   c.fe_id === fe_id ? currenComponent : c
      // );
      // return {
      //   ...state,
      //   componentList:updateComponentList
      // };
      const newComponentList = componentList.map((c) =>
        c.fe_id === fe_id ? { ...c, isHidden } : c
      );
      let newSelectId = "";
      // const newSelectId = getNextSelectId(fe_id, componentList);
      if (isHidden) {
        newSelectId = getNextSelectId(fe_id, componentList);
      } else {
        newSelectId = fe_id;
      }
      return {
        ...state,
        componentList: newComponentList,
        selectId: newSelectId,
      };
    },
    //锁定组件
    lockedComponent: (
      state: ComponentStateType,
      action: PayloadAction<{ fe_id: string }>
    ) => {
      const { fe_id } = action.payload;
      const newComponentList = state.componentList.map((c) =>
        c.fe_id === fe_id ? { ...c, isLocked: !c.isLocked } : c
      );
      return {
        ...state,
        componentList: newComponentList,
      };
    },
    //复制组件
    copyComponent: (state: ComponentStateType) => {
      const { selectId, componentList = [] } = state;
      const selectedComponent = componentList.find((c) => c.fe_id === selectId);
      if (selectedComponent == null) return;
      return {
        ...state,
        copiedComponent: cloneDeep(selectedComponent),
      };
    },
    //粘贴组件
    pasteComponent: (state: ComponentStateType) => {
      const { copiedComponent } = state;
      if (copiedComponent == null) return;
      //粘贴时,要修改fe_id,id不能重复
      return insertNewComponent(state, { ...copiedComponent, fe_id: nanoid() });
    },
    //选中上一个组件
    selectPreviousComponent: (state: ComponentStateType) => {
      const { selectId, componentList = [] } = state;
      const selectedIndex = componentList.findIndex(
        (c) => c.fe_id === selectId
      );
      //未找到
      if (selectedIndex < 0) return;
      //选中第一个
      if (selectedIndex <= 0) return;
      return {
        ...state,
        selectId: componentList[selectedIndex - 1].fe_id,
      };
    },
    //选中下一个组件
    selectNextComponent: (state: ComponentStateType) => {
      const { selectId, componentList = [] } = state;
      const selectedIndex = componentList.findIndex(
        (c) => c.fe_id === selectId
      );
      //未找到
      if (selectedIndex < 0) return;
      //选中最后一个
      if (selectedIndex + 1 === componentList.length) return;
      return {
        ...state,
        selectId: componentList[selectedIndex + 1].fe_id,
      };
    },
    //修改标题
    changeComponentTitle: (
      state: ComponentStateType,
      action: PayloadAction<{ fe_id: string; title: string }>
    ) => {
      const { fe_id, title } = action.payload;
      const updatedComponents = state.componentList.map((component) =>
        component.fe_id === fe_id ? { ...component, title } : component
      );

      return {
        ...state,
        componentList: updatedComponents,
      };
    },
    //移动组件
    moveComponent: (
      state: ComponentStateType,
      action: PayloadAction<{ oldIndex: number; newIndex: number }>
    ) => {
      const { componentList: currenComponentList } = state;
      const { oldIndex, newIndex } = action.payload;
      const newComponentList = arrayMove(
        currenComponentList,
        oldIndex,
        newIndex
      );
      return {
        ...state,
        componentList: newComponentList,
      };
    },
  },
});

export const {
  resetComponents,
  changeSelectId,
  addComponent,
  updateComponentProps,
  deleteComponent,
  hiddenComponent,
  lockedComponent,
  copyComponent,
  pasteComponent,
  selectPreviousComponent,
  selectNextComponent,
  changeComponentTitle,
  moveComponent,
} = componentsSlice.actions;
export default componentsSlice.reducer;
